﻿using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Web;
using Ornament.Text;
using Qi;

namespace Ornament.Messages
{
    public class Template
    {
        private string _templateContent;
        private string[] _namedFormatter;

        public Template()
        {
        }

        internal Template(InfoType infoType)
        {
            InfoType = infoType;
        }

        /// <summary>
        /// Key of this Template Config. may is "edit", "List" or somthing you want to use page
        /// </summary>
        public virtual string Name { get; set; }

        /// <summary>
        /// Gets or Sets the path of template file;
        /// </summary> 
        public virtual string Path { get; set; }

        /// <summary>
        /// Gets or Sets the version of this instance.
        /// </summary>
        public virtual int Version { get; protected set; }

        /// <summary>
        /// Gets the Type of this template.
        /// </summary>
        public virtual InfoType InfoType { get; protected set; }
        /// <summary>
        /// 
        /// </summary>
        private string TemplateContent
        {
            get
            {
                if (_templateContent == null)
                {
                    string path = ApplicationHelper.MapPath(Path);

                    using (var w = new StreamReader(path))
                    {
                        _templateContent = w.ReadToEnd();
                    }
                }
                return _templateContent;
            }
        }

        /// <summary>
        /// The Variables in the template content,such as [named].
        /// </summary>
        private string[] NamedFormatters
        {
            get
            {
                if (_namedFormatter == null)
                {
                    _namedFormatter = NamedFormatterHelper.CollectVariable(TemplateContent);
                }
                return _namedFormatter;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="infoDatabase"></param>
        /// <param name="templateValues"></param>
        /// <returns></returns>
        public virtual string Fromat(Info infoDatabase)
        {
            Dictionary<string, string> templateValues = infoDatabase.Content.FillTemplateValue(infoDatabase);

            foreach (string s in NamedFormatters)
            {
                //if couldn't find the Valibel in mapping, it will try to 
                //get value by reflact.
                if (!templateValues.ContainsKey(s))
                {
                    PropertyInfo propertyInfo = infoDatabase.Content.Value.GetType().GetProperty(s);
                    if (propertyInfo != null)
                    {
                        templateValues[s] = propertyInfo.GetValue(infoDatabase.Content.Value, null).ToString();
                    }
                }
            }

            return NamedFormatterHelper.Replace(TemplateContent, templateValues);
        }

        public override bool Equals(object obj)
        {
            var template = obj as Template;
            if (template == null)
                return false;
            return template.Name == Name && template.InfoType.Id == InfoType.Id;
        }

        public override int GetHashCode()
        {
            return (Name + InfoType.Id).GetHashCode();
        }
    }
}